/**
 * Copyright (c) 2006 RiseSoft Co.,Ltd  
 * $Header$
 */
package net.risesoft.risebi.collection.web.admin;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import net.risesoft.risebi.collection.commons.constants.SystemConstants;
import net.risesoft.risebi.collection.commons.miscellaneouse.ExtRecordsMeta;
import net.risesoft.risebi.collection.model.Application;
import net.risesoft.risebi.collection.model.StatisticalObjectTree;
import net.risesoft.risebi.collection.model.StatisticalObjectTreeNode;
import net.risesoft.risebi.collection.model.User;
import net.risesoft.risebi.collection.service.ApplicationManager;
import net.risesoft.risebi.collection.service.CatalogManager;
import net.risesoft.risebi.collection.service.StatisticalObjectTreeManager;
import net.risesoft.risebi.collection.service.StatisticalObjectTreeNodeManager;
import net.risesoft.risebi.collection.web.BaseAction;
import net.risesoft.risebi.commons.exception.SameEntityException;
import net.risesoft.risebi.commons.struts2extension.Trimable;
import net.risesoft.risebi.commons.util.ExceptionUtil;
import net.risesoft.risebi.commons.util.GUID;
import net.risesoft.risebi.commons.util.JSONUtil;
import net.risesoft.risebi.commons.util.PropsUtil;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;

import org.apache.commons.beanutils.LazyDynaBean;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.opensymphony.xwork2.ActionInvocation;

/**
 *
 * @author <a href="mailto: chenjian@risesoft.net">陈健</a>
 * @version $Revision$
 * 
 */
public class StatisticalObjectAction extends BaseAction implements Trimable {	
	private static final long serialVersionUID = -8386471373870530822L;
	private static final Logger logger = Logger.getLogger(StatisticalObjectAction.class);	
	private String treeId = "user-tree";
	
	private StatisticalObjectTree sot;
	private StatisticalObjectTreeNode sotNode;
	private StatisticalObjectTreeManager statisticalObjectTreeManager;
	private StatisticalObjectTreeNodeManager statisticalObjectTreeNodeManager;
	private ApplicationManager applicationManager;

	private CatalogManager catalogManager;
	private String sotnodes;
	private List allTreeScopeSotNodes;
	private List<Application> applications;
	
	public ApplicationManager getApplicationManager() {
		return applicationManager;
	}

	public void setApplicationManager(ApplicationManager applicationManager) {
		this.applicationManager = applicationManager;
	}

	public StatisticalObjectTreeNodeManager getStatisticalObjectTreeNodeManager() {
		return statisticalObjectTreeNodeManager;
	}
	
	public List<Application> getApplications() {
		return applications;
	}

	public void setApplications(List<Application> applications) {
		this.applications = applications;
	}

	public StatisticalObjectTreeManager getStatisticalObjectTreeManager() {
		return statisticalObjectTreeManager;
	}

	public CatalogManager getCatalogManager() {
		return catalogManager;
	}

	
	public StatisticalObjectTreeNode getSotNode() {
		return sotNode;
	}

	public void setSotNode(StatisticalObjectTreeNode sotNode) {
		this.sotNode = sotNode;
	}
	
	public String getSotnodes() {
		return sotnodes;
	}

	public void setSotnodes(String sotnodes) {
		this.sotnodes = sotnodes;
	}
	
	public List getAllTreeScopeSotNodes() {
		return allTreeScopeSotNodes;
	}

	public void setAllTreeScopeSotNodes(List allTreeScopeSotNodes) {
		this.allTreeScopeSotNodes = allTreeScopeSotNodes;
	}

	public void setStatisticalObjectTreeNodeManager(StatisticalObjectTreeNodeManager statisticalObjectTreeNodeManager) {
		this.statisticalObjectTreeNodeManager = statisticalObjectTreeNodeManager;
	}
	
	public void setCatalogManager(CatalogManager catalogManager) {
		this.catalogManager = catalogManager;
	}

	public void setStatisticalObjectTreeManager(StatisticalObjectTreeManager statisticalObjectTreeManager) {
		this.statisticalObjectTreeManager = statisticalObjectTreeManager;
	}
	
	public StatisticalObjectTree getSot() {
		return sot;
	}

	public void setSot(StatisticalObjectTree sot) {
		this.sot = sot;
	}

	public String getTreeId() {
		return treeId;
	}

	public void setTreeId(String treeId) {
		this.treeId = treeId;
	}
	
	public String index() throws Exception {
		return INDEX;
	}

	public String refreshJson() throws Exception {
		try{
			if("jsonModules".equalsIgnoreCase(this.whichJson)){
				
			}else if("jsonAppSoTrees".equalsIgnoreCase(this.whichJson)){
				ArrayList al = new ArrayList();		

				if(this.active_node_id==null){
					List<Application> lst = applicationManager.getAppsByServiceWithPermission(this.getDefaultService().getGuid(), this.getSessionUser());
					for(Application a : lst){
						boolean isleaf = true;
						List<StatisticalObjectTree> lst1 = statisticalObjectTreeManager.getAllByApp(a.getGuid());
						if(lst1.size()>0){
							isleaf = false;
						}
						LazyDynaBean ldb = new LazyDynaBean();
						ldb.set("guid", a.getGuid());
						ldb.set("parentGuid", "");
						ldb.set("name", a.getChineseName());
						ldb.set("_node_type", "3");
						ldb.set("_is_leaf", isleaf);
						al.add(ldb);
					}					
				}else if("3".equalsIgnoreCase(this.active_node_type)){
					List<StatisticalObjectTree> lst = statisticalObjectTreeManager.getAllByApp(this.active_node_id);
					for(StatisticalObjectTree a : lst){
						LazyDynaBean ldb = new LazyDynaBean();
						ldb.set("guid", a.getGuid());
						ldb.set("parentGuid", this.active_node_id);
						ldb.set("name", a.getName());
						ldb.set("_node_type", "5");
						ldb.set("_is_leaf", true);
						al.add(ldb);
					}					
				}				

				this.json = JSONUtil.getJsonString(null, null, al);				
			}
		}catch(Exception e){
			this.json = "[]";
			e.printStackTrace();
		}
 
		return "refreshJson";
	}

	/**
	 * 准备增加统计对象树的页面
	 * 
	 * @return
	 */
	public String prepareAddSot() {
		applications = applicationManager.getObjects(Application.class);
		return "prepareAddSot";
	}

	/**
	 * 增加统计对象树
	 * 
	 * @return
	 * @throws Exception
	 */
	public String addSot() throws Exception {
		try {
			User user = getSessionUser();
			Application app = user.getDefaultApp();
			
//			排重
			String sql = "select count(*) from StatisticalObjectTree a where a.name='"+sot.getName()+"' and a.application.guid='"+app.getGuid()+"'";
			Integer count = statisticalObjectTreeManager.getCount(sql);
			if(count>0){
				throw new SameEntityException();
			}
			
			if(logger.isDebugEnabled()){
				logger.debug("开始增加统计对象树，树的名称："+sot.getName());
			}
			
			String guid = new GUID().toString();
			sot.setGuid(guid);
			
			if(StringUtils.isNotBlank(sot.getApplication().getGuid())){
				Application application  = (Application)applicationManager.getObject(Application.class, sot.getApplication().getGuid());
				sot.setApplication(application);
			}
			
			statisticalObjectTreeManager.saveObject(sot);
			
			if(logger.isDebugEnabled()){
				logger.debug("成功增加统计对象树，树的名称："+sot.getName());
			}
			
			return "addSot";
		} catch (Exception e) {
			logger.error(ExceptionUtil.transformException(e));
			applications = applicationManager.getObjects(Application.class);
			return INPUT;
		}
	}
	
	/**
	 * 准备修改统计对象树的页面
	 * 
	 * @return
	 * @throws Exception
	 */
	public String prepareEditSot() throws Exception {
		sot = (StatisticalObjectTree)statisticalObjectTreeManager.getObject(StatisticalObjectTree.class, node);
		applications = applicationManager.getObjects(Application.class);
		return "prepareEditSot";
	}
	
	/**
	 * 修改统计对象树
	 * 
	 * @return
	 * @throws Exception
	 */
	public String editSot() throws Exception {
//		排重，不能有同名的统计对象树
		String sql = "select count(*) from StatisticalObjectTree a where a.name='"+sot.getName()+"' and a.guid<>'"+sot.getGuid()+"'";
		Integer count = statisticalObjectTreeManager.getCount(sql);
		if(count>0)
			throw new SameEntityException();
		
		if(logger.isDebugEnabled()){
			logger.debug("开始修改统计对象树，修改统计对象树的GUID："+sot.getGuid());
		}
		
		StatisticalObjectTree oldSot = (StatisticalObjectTree)statisticalObjectTreeManager.getObject(StatisticalObjectTree.class, sot.getGuid());
		oldSot.setName(sot.getName());
		oldSot.setType(sot.getType());
//		oldSot.setDefaulted(sot.getDefaulted());
		oldSot.setDescription(sot.getDescription());
		oldSot.setEnabled(sot.getEnabled());
		oldSot.setIconPath(sot.getIconPath());
		oldSot.setTabIndex(sot.getTabIndex());
		//byb rem 20090601 	oldSot.setDefaultNodeGuid(sot.getDefaultNodeGuid());
		//byb rem 20090601 	oldSot.setDefaultRootInstanceGuid(sot.getDefaultRootInstanceGuid());
		
		if(StringUtils.isNotBlank(sot.getApplication().getGuid())){
			Application application  = (Application)applicationManager.getObject(Application.class, sot.getApplication().getGuid());
			oldSot.setApplication(application);
		}
		
		statisticalObjectTreeManager.saveObject(oldSot);
		
		if(logger.isDebugEnabled()){
			logger.debug("成功修改统计对象树，修改统计对象树的GUID："+sot.getGuid());
		}
		
//		提供transfer所需要的内容，结点ID，修改后的名称
		node = sot.getGuid();
		editedName = sot.getName();
		
		return "editSot";
	}
	
	/**
	 * 删除统计对象树
	 * 
	 * @return
	 * @throws Exception
	 */
	public String removeSot() throws Exception {
		if(logger.isDebugEnabled()){
			logger.debug("删除统计对象树开始，统计对象树的GUID："+node);
		}
		
		statisticalObjectTreeManager.removeObject(StatisticalObjectTree.class, node);
		
		if(logger.isDebugEnabled()){
			logger.debug("成功删除统计对象树，统计对象树的GUID："+node);
		}
		return "removeSot";
	}
	
	/**
	 * 准备增加统计对象结点的页面
	 * 
	 * @return
	 * @throws Exception
	 */
	public String prepareAddSotNode() throws Exception {
		if(source.equals("statisticalObjectTree")){
			allTreeScopeSotNodes = statisticalObjectTreeNodeManager.getAllBySOT(node);
		}else{
			allTreeScopeSotNodes = statisticalObjectTreeNodeManager.getAllTreeScopeBySotNode(node);
		}
		
		return "prepareAddSotNode";
	}
	
	/**
	 * 从catalog中获得所有的统计对象
	 * 
	 * @return
	 * @throws Exception
	 */
	public String getAllCatalogWithSo() throws Exception {
		if(logger.isDebugEnabled()){
			logger.debug("开始从Catalog中获取所有统计对象");
		}
		User user = getSessionUser();
		Application application = user.getDefaultApp();
		List list = catalogManager.getCatalogWithSoByApp(application.getGuid(),true);
		if(logger.isDebugEnabled()){
			logger.debug("从Catalog中获取所有统计对象，共 "+list.size()+" 个");
		}
		
		ExtRecordsMeta erm = new ExtRecordsMeta();
		erm.setResults(list.size());
		erm.setRows(list);
		
		try {
			JsonConfig config = new JsonConfig();
			config.setExcludes(new String[]{"application","soType"});
			JSONObject jsonObject = JSONObject.fromObject(erm,config);
			json = jsonObject.toString();
		} catch (Exception e) {
			logger.error(ExceptionUtil.transformException(e));
		}
		
		return "getAllCatalogWithSo";
	}
	
	/**
	 * 批量增加统计对象树的结点，注意根结点只能有一个，catalog结点在树中只能存在一个
	 * 
	 * @return
	 * @throws Exception
	 */
	public String addSotNode() throws Exception {
		if(source.equals("statisticalObjectTree")){
			if(logger.isDebugEnabled()){
				logger.debug("开始增加在统计对象树结点："+node+"下增加结点："+sotnodes);
			}
			statisticalObjectTreeNodeManager.insertSotNodes(sotnodes, node, null);
			if(logger.isDebugEnabled()){
				logger.debug("成功增加在统计对象树结点："+node+"下增加结点："+sotnodes);
			}
		}else{
			StatisticalObjectTreeNode aSotNode = (StatisticalObjectTreeNode) statisticalObjectTreeNodeManager.getObject(StatisticalObjectTreeNode.class, node);
			if(logger.isDebugEnabled()){
				logger.debug("开始增加在统计对象树结点："+node+"下增加结点："+sotnodes);
			}
			statisticalObjectTreeNodeManager.insertSotNodes(sotnodes, aSotNode.getStatisticalObjectTree().getGuid(), node);
			if(logger.isDebugEnabled()){
				logger.debug("成功增加在统计对象树结点："+node+"下增加结点："+sotnodes);
			}
			
			forwardUrl = "/admin/welcome.action?source=statisticalObjectTreeNode";
		}
		
		return "addSotNode";
	}
	
	/**
	 * 准备修改统计对象结点的页面
	 * 
	 * @return
	 * @throws Exception
	 */
	public String prepareEditSotNode() throws Exception {
		sotNode = (StatisticalObjectTreeNode) statisticalObjectTreeNodeManager.getObject(StatisticalObjectTreeNode.class, node);
		return "prepareEditSotNode";
	}
	
	/**
	 * 修改统计对象结点
	 * 
	 * @return
	 * @throws Exception
	 */
	public String editSotNode() throws Exception {
		if(logger.isDebugEnabled()){
			logger.debug("开始修改统计对象树结点信息，修改的结点Guid："+sotNode.getGuid()+"，修改的结点名称是："+sotNode.getName());
		}
		StatisticalObjectTreeNode oldSotNode = (StatisticalObjectTreeNode)statisticalObjectTreeNodeManager.getObject(StatisticalObjectTreeNode.class, sotNode.getGuid());
		oldSotNode.setDescription(sotNode.getDescription());
		oldSotNode.setTabIndex(sotNode.getTabIndex());
		oldSotNode.setParentColumnName(sotNode.getParentColumnName());
		oldSotNode.setSelfColumnName(sotNode.getSelfColumnName());
		statisticalObjectTreeNodeManager.saveObject(oldSotNode);
		
		if(logger.isDebugEnabled()){
			logger.debug("成功修改统计对象树结点信息，修改的结点Guid："+sotNode.getGuid()+"，修改的结点名称是："+sotNode.getName());
		}
		
//		提供transfer所需要的内容，结点ID，修改后的名称
		node = sotNode.getGuid();
		editedName = sotNode.getName();
		
		return "editSotNode";
	}
	
	/**
	 * 删除统计对象结点
	 * 
	 * @return
	 * @throws Exception
	 */
	public String removeSotNode() throws Exception {
		statisticalObjectTreeNodeManager.removeObject(StatisticalObjectTreeNode.class, node);
		return "removeSotNode";
	}
	
	/**
	 * 从dyna_catalog_xxx中获得列表，用于json
	 * 
	 * @return
	 * @throws Exception
	 */
	public String getOrgsFromCatalog() throws Exception {
		if(limit==0){
			String ps = PropsUtil.getProperty("OrgManageAction_getSoCollections");
			if(ps==null){
				//ps = PropsUtil.getProperty(SystemConstants.REPORT_PAGINGSIZE);
				ps = "10";
			}
			limit = Integer.valueOf(ps); 
		}
		
		Map map = statisticalObjectTreeNodeManager.getOrgsFromCatalog(node, start, limit);
		int count = (Integer) map.get("count");
		List list = (List) map.get("list");
		
		ExtRecordsMeta erm = new ExtRecordsMeta();
		erm.setResults(count);
		erm.setRows(list);
		
		try {
			JsonConfig config = new JsonConfig();
			config.setExcludes(new String[]{"$type$","item_code"});
			JSONObject jsonObject = JSONObject.fromObject(erm,config);
			json = jsonObject.toString();
			System.out.println(json);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "getOrgsFromCatalog";
	}

	/* (non-Javadoc)
	 * @see net.risesoft.commons.struts2extension.Trimable#afterTrim(com.opensymphony.xwork2.ActionInvocation)
	 */
	public void afterTrim(ActionInvocation invocation) {
		// TODO Auto-generated method stub
		
	}

	/* (non-Javadoc)
	 * @see net.risesoft.commons.struts2extension.Trimable#preTrim(com.opensymphony.xwork2.ActionInvocation)
	 */
	public boolean preTrim(ActionInvocation invocation) {
		return true;
	}
}
